/******************** (C) COPYRIGHT 2019 STMicroelectronics ********************
 * File Name          : sensor.c
 * Author             : AMS - RF Application team
 * Version            : V2.0.0
 * Date               : 26-February-2019
 * Description        : Sensor init and sensor state machines
 ********************************************************************************
 * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
 * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
 * AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
 * INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
 * CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
 * INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
 *******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include <stdio.h>
#include <string.h>
#include "ble_const.h" 
#include "bluenrg_lp_stack.h"
#include "OTA_btl.h" 

#include "gatt_db.h"
#include "rf_driver_hal_vtimer.h"
#include "gap_profile.h"
#include "clock.h"

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#ifndef DEBUG
#define DEBUG 0
#endif

#if DEBUG
#include <stdio.h>
#define PRINTF(...) printf(__VA_ARGS__)
#else
#define PRINTF(...)
#endif

#define UPDATE_CONN_PARAM 0 //0
#define ADV_INTERVAL_MIN_MS  200
#define ADV_INTERVAL_MAX_MS  200

/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
volatile uint8_t set_connectable = 1;
uint16_t connection_handle = 0;
uint8_t connInfo[20];
int connected = FALSE;

static VTIMER_HandleType sensorTimerHandle;

volatile uint8_t request_free_fall_notify = FALSE; 

BOOL sensor_board = FALSE; // It is True if sensor board has been detected

#if UPDATE_CONN_PARAM
#define UPDATE_TIMER 2 //TBR
static VTIMER_HandleType l2cap_TimerHandle;
int l2cap_request_sent = FALSE;
static uint8_t l2cap_req_timer_expired = FALSE; 
#endif

#define SENSOR_TIMER 1
#define ACC_UPDATE_INTERVAL_MS 200
static uint8_t sensorTimer_expired = FALSE;
static uint8_t tempTimer_expired = FALSE;

#ifndef SENSOR_ACCELEROMETER_EMULATION


#endif 

#ifndef SENSOR_PRESSURE_TEMPERATURE_EMULATION

/* We use the real pressure-temperature sensor on BlueNRG-LP Kit */

/* LPS22HH initialization */
lps22hh_ctx_t pressureHandle;

#endif 
  
/* Private function prototypes -----------------------------------------------*/

static Advertising_Set_Parameters_t Advertising_Set_Parameters[1];

static uint8_t m_u8_AdvData[] =
{
    0x02,0x01,0x06,
    0x03,0x02,0x00,0xF0,
    0x17,0xFF,0xA9,0x00,  
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x82
};
static uint8_t m_u8_AdvResponseData[] =
{
//    0x08, AD_TYPE_COMPLETE_LOCAL_NAME,'B','l','u','e','N','R','G' ,
	0x06,0x09,'2','2','2','2','2',
//    0x0B,0xFF,0xA9,0x00,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x00,0x00
	0x11,0x06,0x8a,0x97,0xf7,0xc0,0x85,0x06,0x11,0xe3,0xba,0xa7,0x08,0x00,0x20,0x0c,0x9a,0x66
};
//static uint8_t device_name[] = {'B', 'l', 'u', 'e', 'N', 'R', 'G'};
static uint8_t device_name[] = {'2','2','2','2','2'};
void Set_DeviceConnectable(void) ;
uint8_t  Sensor_DeviceInit()
{
  uint8_t ret;
  uint16_t service_handle, dev_name_char_handle, appearance_char_handle;
  
  aci_hal_set_tx_power_level(0, 24);
  
  /* GATT Init */
  ret = aci_gatt_srv_init();
  if (ret != BLE_STATUS_SUCCESS) {
    PRINTF("aci_gatt_srv_init() failed: 0x%02x\r\n", ret);
    return ret;
  }
  
  /* GAP Init */
  ret = aci_gap_init(GAP_PERIPHERAL_ROLE, 0, 0x07, STATIC_RANDOM_ADDR, &service_handle, &dev_name_char_handle, &appearance_char_handle);
  if (ret != BLE_STATUS_SUCCESS) {
    PRINTF("aci_gap_init() failed: 0x%02x\r\n", ret);
    return ret;
  }
 
  /* Update device name */
  Gap_profile_set_dev_name(0, sizeof(device_name), device_name);
  
  ret = aci_gap_set_authentication_requirement(NO_BONDING,
                                               MITM_PROTECTION_NOT_REQUIRED,
                                               SC_IS_NOT_SUPPORTED,
                                               KEYPRESS_IS_NOT_SUPPORTED,
                                               7, 
                                               16,
                                               0x00,
                                               0);
  if(ret != BLE_STATUS_SUCCESS) {
    PRINTF("aci_gap_set_authentication_requirement()failed: 0x%02x\r\n", ret);
    return ret;
  }
  
  aci_gap_set_advertising_configuration( 0, GAP_MODE_GENERAL_DISCOVERABLE,
                                              ADV_PROP_CONNECTABLE|ADV_PROP_SCANNABLE|ADV_PROP_LEGACY,
                                              (ADV_INTERVAL_MIN_MS*1000)/625, (ADV_INTERVAL_MAX_MS*1000)/625, 
                                              ADV_CH_ALL,
                                              0,NULL,
                                              ADV_NO_WHITE_LIST_USE,
                                              0, /* 0 dBm */
                                              LE_1M_PHY, /* Primary advertising PHY */
                                              0, /* 0 skips */
                                              LE_1M_PHY, /* Secondary advertising PHY. Not used with legacy advertising. */
                                              0, /* SID */
                                              0 /* No scan request notifications */);
  
  aci_gap_set_advertising_data( 0, ADV_COMPLETE_DATA, sizeof(m_u8_AdvData), m_u8_AdvData);
	
	aci_gap_set_scan_response_data(0,sizeof(m_u8_AdvResponseData),m_u8_AdvResponseData);


//  /* Add Environmental Sensor Service */
//  ret = Add_CGM_Sensor_Service();
//  if(ret == BLE_STATUS_SUCCESS) {
//    PRINTF("Environmental service added successfully.\n");
//  } else {
//    PRINTF("Error while adding Environmental service: 0x%04x\r\n", ret);
//    return ret;
//  }
//  
  ret = OTA_Add_Btl_Service();
  if(ret == BLE_STATUS_SUCCESS)
    PRINTF("OTA service added successfully.\n");
  else
    PRINTF("Error while adding OTA service.\n");
 
Set_DeviceConnectable();
  return BLE_STATUS_SUCCESS;
}



#if UPDATE_CONN_PARAM
void l2cap_UpdateTimeoutCB(void *param)
{
  l2cap_req_timer_expired = TRUE;
}
#endif

/*******************************************************************************
 * Function Name  : Set_DeviceConnectable.
 * Description    : Puts the device in connectable mode.
 * Input          : None.
 * Output         : None.
 * Return         : None.
 *******************************************************************************/

void Set_DeviceConnectable(void)
{  
  uint8_t ret;
	
  
  Advertising_Set_Parameters[0].Advertising_Handle = 0;
  Advertising_Set_Parameters[0].Duration = 0;
  Advertising_Set_Parameters[0].Max_Extended_Advertising_Events = 0;
  
  ret = aci_gap_set_advertising_enable(ENABLE, 1, Advertising_Set_Parameters); 
  
  if(ret != BLE_STATUS_SUCCESS)
  {
    PRINTF("aci_gap_set_advertising_enable() failed: 0x%02x\r\n",ret);
//    BSP_LED_On(BSP_LED3);  
  }
  else
    PRINTF("aci_gap_set_advertising_enable() --> SUCCESS\r\n");
}

///*******************************************************************************
// * Function Name  : APP_Tick.
// * Description    : Sensor Demo state machine.
// * Input          : None.
// * Output         : None.
// * Return         : None.
// *******************************************************************************/
//void APP_Tick(void)
//{
//#if UPDATE_CONN_PARAM    
//  uint8_t ret = 0; 
//#endif 
//  /* Make the device discoverable */
////  if(set_connectable) {
////    Set_DeviceConnectable();
////    set_connectable = FALSE;
////  }

//#if UPDATE_CONN_PARAM      
//  /* Connection parameter update request */
//  if(connected && !l2cap_request_sent && l2cap_req_timer_expired){
//    ret = aci_l2cap_connection_parameter_update_req(connection_handle, 9, 20, 0, 600); //24, 24
//    PRINTF("aci_l2cap_connection_parameter_update_req(): 0x%02x\r\n", ret); (void)ret;
//    l2cap_request_sent = TRUE;
//  }
//#endif
//		
//}

///* ***************** BlueNRG-LP Stack Callbacks ********************************/

///*******************************************************************************
// * Function Name  : hci_le_connection_complete_event.
// * Description    : This event indicates that a new connection has been created.
// * Input          : See file bluenrg1_events.h
// * Output         : See file bluenrg1_events.h
// * Return         : See file bluenrg1_events.h
// *******************************************************************************/
//void hci_le_connection_complete_event(uint8_t Status,
//                                      uint16_t Connection_Handle,
//                                      uint8_t Role,
//                                      uint8_t Peer_Address_Type,
//                                      uint8_t Peer_Address[6],
//                                      uint16_t Conn_Interval,
//                                      uint16_t Conn_Latency,
//                                      uint16_t Supervision_Timeout,
//                                      uint8_t Master_Clock_Accuracy)
//{
//#if UPDATE_CONN_PARAM  
//  uint8_t ret; 
//#endif
//  
//  if(Status != BLE_STATUS_SUCCESS)
//    return;
//  
//  connected = TRUE;
//  connection_handle = Connection_Handle;
//  
//#if UPDATE_CONN_PARAM    
//  l2cap_request_sent = FALSE;
//  
//   /* Start the l2cap Timer */
//  l2cap_TimerHandle.callback = l2cap_UpdateTimeoutCB;  
//  ret = HAL_VTIMER_StartTimerMs(&l2cap_TimerHandle, CLOCK_SECOND*2);
//  if (ret != BLE_STATUS_SUCCESS) {
//    PRINTF("HAL_VTIMER_StartTimerMs(l2cap) failed; 0x%02x\r\n", ret);
//  } else {
//    l2cap_req_timer_expired = FALSE;
//  }
//#endif
//    
//}/* end hci_le_connection_complete_event() */

///*******************************************************************************
// * Function Name  : hci_le_enhanced_connection_complete_event.
// * Description    : This event indicates that a new connection has been created
// * Input          : See file bluenrg_lp_events.h
// * Output         : See file bluenrg_lp_events.h
// * Return         : See file bluenrg_lp_events.h
// *******************************************************************************/
//void hci_le_enhanced_connection_complete_event(uint8_t Status,
//                                               uint16_t Connection_Handle,
//                                               uint8_t Role,
//                                               uint8_t Peer_Address_Type,
//                                               uint8_t Peer_Address[6],
//                                               uint8_t Local_Resolvable_Private_Address[6],
//                                               uint8_t Peer_Resolvable_Private_Address[6],
//                                               uint16_t Conn_Interval,
//                                               uint16_t Conn_Latency,
//                                               uint16_t Supervision_Timeout,
//                                               uint8_t Master_Clock_Accuracy)
//{
//  
//  hci_le_connection_complete_event(Status,
//                                   Connection_Handle,
//                                   Role,
//                                   Peer_Address_Type,
//                                   Peer_Address,
//                                   Conn_Interval,
//                                   Conn_Latency,
//                                   Supervision_Timeout,
//                                   Master_Clock_Accuracy);
//}

///*******************************************************************************
// * Function Name  : hci_disconnection_complete_event.
// * Description    : This event occurs when a connection is terminated.
// * Input          : See file bluenrg1_events.h
// * Output         : See file bluenrg1_events.h
// * Return         : See file bluenrg1_events.h
// *******************************************************************************/
//void hci_disconnection_complete_event(uint8_t Status,
//                                      uint16_t Connection_Handle,
//                                      uint8_t Reason)
//{
//  connected = FALSE;
//  /* Make the device connectable again. */
//  set_connectable = TRUE;
//  connection_handle =0;
//  
////  BSP_LED_On(BSP_LED1);//activity led   

//  OTA_terminate_connection();

//}/* end hci_disconnection_complete_event() */


///*******************************************************************************
// * Function Name  : aci_gatt_srv_attribute_modified_event.
// * Description    : This event occurs when an attribute is modified.
// * Input          : See file bluenrg1_events.h
// * Output         : See file bluenrg1_events.h
// * Return         : See file bluenrg1_events.h
// *******************************************************************************/
//void aci_gatt_srv_attribute_modified_event(uint16_t Connection_Handle,
//                                           uint16_t Attr_Handle,
//                                           uint16_t Attr_Data_Length,
//                                           uint8_t Attr_Data[])
//{

//  OTA_Write_Request_CB(Connection_Handle, Attr_Handle, Attr_Data_Length, Attr_Data); 

//}


//void aci_hal_end_of_radio_activity_event(uint8_t Last_State,
//                                         uint8_t Next_State,
//                                         uint32_t Next_State_SysTime)
//{

//  if (Next_State == 0x02) /* 0x02: Connection event slave */
//  {
//    OTA_Radio_Activity(Next_State_SysTime);  
//  }

//}

//#if UPDATE_CONN_PARAM

//void aci_l2cap_connection_update_resp_event(uint16_t Connection_Handle,
//                                            uint16_t Result)
//{
//   PRINTF("aci_l2cap_connection_update_resp_event; 0x%02x\r\n", Result);
//}

//void aci_l2cap_command_reject_event(uint16_t Connection_Handle,
//                                    uint8_t Identifier,
//                                    uint16_t Reason,
//                                    uint8_t Data_Length,
//                                    uint8_t Data[])
//{
//  PRINTF("aci_l2cap_command_reject_event; 0x%02x\r\n", Reason);
//}
//#endif 

//void hci_le_connection_update_complete_event(uint8_t Status,
//                                             uint16_t Connection_Handle,
//                                             uint16_t Conn_Interval,
//                                             uint16_t Conn_Latency,
//                                             uint16_t Supervision_Timeout)
//{
//  PRINTF("hci_le_connection_update_complete_event; %d\r\n", Conn_Interval);
//}


//void aci_att_exchange_mtu_resp_event(uint16_t Connection_Handle,
//                                     uint16_t Server_RX_MTU)
//{
//  OTA_att_exchange_mtu_resp_CB(Connection_Handle, Server_RX_MTU);
//}

//void hci_le_data_length_change_event(uint16_t Connection_Handle,
//                                     uint16_t MaxTxOctets,
//                                     uint16_t MaxTxTime,
//                                     uint16_t MaxRxOctets,
//                                     uint16_t MaxRxTime)
//{
//  OTA_data_length_change_CB(Connection_Handle);  
//}

